package compile;

/**
 * @author SongJun
 * @description TODO:
 * @date 2021/9/28 16:49
 */
public class RefResolver extends AstVisitor {
    Prog prog;

    Object visitProg(Prog prog){
        this.prog = prog;
        for(Statement x : prog.getStmts()){
            if(x instanceof FunctionCall){
                this.resolveFunctionCall(prog, (FunctionCall)x);
            } else {
                this.visitFunctionDecl((FunctionDecl) x);
            }
        }
        return null;
    }
    Object visitFunctionBody(FunctionBody functionBody){
        if(this.prog != null){
            for(Statement x : functionBody.stmts){
                return this.resolveFunctionCall(this.prog, (FunctionCall)x);
            }
        }
        return null;
    }
    private Object resolveFunctionCall(Prog prog, FunctionCall functionCall){
        FunctionDecl functionDecl = this.findFunctionDecl(prog,functionCall.name);
        if (functionDecl != null){
            functionCall.definition = functionDecl;
        } else {
            if (!functionCall.name.equals("println")){  //系统内置函数不用报错
                System.out.println("Error: cannot find definition of function " + functionCall.name);
            }
        }
        return null;
    }
    private FunctionDecl findFunctionDecl(Prog prog, String name){
        for(Statement x : prog.getStmts()){
            if(x instanceof FunctionDecl
                    && ((FunctionDecl) x).getName().equals(name)){
                return (FunctionDecl)x;
            }
        }
        return null;
    }
}
